aiui.define(['jquery'],function($){
    "use strict";
    var ELEM = 'aiui-form',
    FilterName = 'aiui-filter',
    body = $('body'),
    form={
        v:'1.0.0',
        /**
         * 添加回调函数
         * @param {string} name 事件名称
         * @param {Function} callback 回调函数
         */
        on:function(name,callback){
            this.event[name] =  callback;
        },
        /**
         * 事件管理器
         */
        event:{},
        /**
         * form渲染
         * @param {Document} dom formdom
         * @param {string} type 类型
         * @param {string} filter 过滤器
         */
        render:function(dom,type,filter){
            if(typeof dom ==="string") dom = document.querySelector(dom);
            if(dom.FormClass){
                dom.FormClass.render(type,filter);
            }else{
                dom.FormClass = new FormClass(dom,type,filter);
            }
        },
        /**
         * 自动渲染方法
         */
        init:function(){
            var that = this;
            var forms= $('*['+ELEM+']');
            $.each(forms,function(index,item){
                that.render(item);
            })
        }
    },
    FormClass=function(dom,type,filter){
        this.config={
            verify: {
                required: [
                    /[\S]+/
                    ,'必填项不能为空'
                ]
                ,phone: [
                    /^1\d{10}$/
                    ,'请输入正确的手机号'
                ]
                ,email: [
                    /^([a-zA-Z0-9_\.\-])+\@(([a-zA-Z0-9\-])+\.)+([a-zA-Z0-9]{2,4})+$/
                    ,'邮箱格式不正确'
                ]
                ,url: [
                    /(^#)|(^http(s*):\/\/[^\s]+\.[^\s]+)/
                    ,'链接格式不正确'
                ]
                ,number: function(value){
                    if(!value || isNaN(value)) return '只能填写数字'
                }
                ,date: [
                    /^(\d{4})[-\/](\d{1}|0\d{1}|1[0-2])([-\/](\d{1}|0\d{1}|[1-2][0-9]|3[0-1]))*$/
                    ,'日期格式不正确'
                ]
                ,identity: [
                    /(^\d{15}$)|(^\d{17}(x|X|\d)$)/
                    ,'请输入正确的身份证号'
                ]
            }
        }
        this.dom = dom;
        this.render(type,filter);
    },
    /**
     * 初始化下拉框
     * @param {FormClass} FormClass form管理器
     * @param {Document} dom 单选框元素
     */
    RadioClass = function(FormClass,dom){
        var that = this,
        props = {
            label:String,
            disabled:Boolean,
            border:Boolean,
            size:String,
            checked:Boolean,
            value:String,
            name:String,
            change:Function
        };
        that.form = FormClass;
        that.config = aiui.getProps(dom,props);
        var template = ['<label class="aiui-radio{{if border.value}} is-bordered{{/if}}{{if checked.value}} is-checked{{/if}}{{if disabled.value}} is-disabled{{/if}}">',
            '<span class="aiui-radio-input">',
                '<span class="aiui-radio-input-inner">',
                '</span>',
            '</span>',
            '{{if label.value}}',
            '<span class="aiui-radio-label">{{label.value}}</span>',
            '{{/if}}',
        '</label>'].join('');
        that.original = dom;
        that.template = template;
        that.render();
    },
    /**
     * 初始化下拉框
     * @param {FormClass} FormClass form管理器
     * @param {Document} dom 复选框元素
     */
    CheckboxClass = function(FormClass,dom){
        var that = this,
        props = {
            label:String,
            disabled:Boolean,
            border:Boolean,
            size:String,
            checked:Boolean,
            value:String,
            name:String,
            indeterminate:Boolean,
            change:Function
        },
        template = ['<label class="aiui-checkbox{{if border.value}} is-bordered{{/if}}{{if checked.value}} is-checked{{/if}}{{if disabled.value}} is-disabled{{/if}}">',
            '<span class="aiui-checkbox-input">',
                '<span class="aiui-checkbox-input-inner">',
                '</span>',
            '</span>',
            '{{if label.value}}',
            '<span class="aiui-checkbox-label">{{label.value}}</span>',
            '{{/if}}',
        '</label>'].join('');
        that.form = FormClass;
        that.config = aiui.getProps(dom,props);
        that.original = dom;
        that.template = template;
        that.render();
    },
    /**
     * 初始化下拉框
     * @param {FormClass} FormClass form管理器
     * @param {Document} dom 开关元素
     */
    SwitchClass = function(FormClass,dom){
        var that = this,props = {
            name:String,
            value:String,
            disabled:Boolean,
            checked:Boolean,
            change:Function,
            truevalue:{
                type:String,
                default:'true',
            },
            falsevalue:{
                type:String,
                default:'false',
            },
            truetext:String,
            falsetext:String
        },
        template = ['<label class="aiui-switch{{if truevalue.value==value.value}} is-checked{{/if}}{{if disabled.value}} is-disabled{{/if}}">',
            '{{if falsetext.value}}',
            '<span class="aiui-switch-label aiui-switch-label-left">{{falsetext.value}}</span>',
            '{{/if}}',
            '<span class="aiui-switch-core">',
            '</span>',
            '{{if truetext.value }}',
            '<span class="aiui-switch-label aiui-switch-label-right">{{truetext.value}}</span>',
            '{{/if}}',
        '</label>'].join('');
        that.form = FormClass;
        that.config = aiui.getProps(dom,props);
        that.template = template;
        that.original = dom;
        that.render();
    },
    /**
     * 初始化下拉框
     * @param {FormClass} FormClass form管理器
     * @param {string} dom 下拉框元素
     */
    SelectClass = function(FormClass,dom){
        var that = this;
        that.form = FormClass;//当前Select属于哪个form
        var props = {
            name:String,//表单名称
            value:String,//选中的值
            disabled:Boolean,//禁用
            multiple:Boolean,//多选
            placeholder:String,
            selected:Function,
            clearable:Boolean,
            size:String,
        }
        that.config = aiui.getProps(dom,props);
        var template = ['<div class="aiui-select" >',
            '{{if multiple.value}}',
            '<div class="aiui-select-tags"><span></span></div>',
            '{{/if}}',
            '<div class="aiui-input {{if disabled.value}}is-disabled{{/if}} icon-suffix{{if size.value}} aiui-input-{{size.value}}{{/if}}">',
                '<input type="text" class="aiui-input-inner" readonly="readonly" placeholder="{{placeholder.value}}" {{if disabled.value}}disabled{{/if}}>',
                '<span class="aiui-input-suffix">',
                    '<span class="aiui-input-suffix-inner">',
                        '<i class="aiui-input-icon aiui-icon-down aiui-select-caret"></i>',
                    '</span>',
                '</span>',
            '</div>',
        '</div>'].join('');
        that.template = template;
        that.original = dom;
        that.render();
    };
    /**
     * Radio表单渲染
     */
    RadioClass.prototype.render = function(){
        var that = this,$original = $(that.original),
        hasRender = $original.next('.aiui-radio'),
        $dom = $(aiui.render(that.template,that.config));
        that.$dom = $dom;
        //如果已经渲染了，就移除渲染的元素
        hasRender[0] && hasRender.remove();
        $original.after($dom);
        //绑定事件
        that.$dom.on('click',function(e){
            e.preventDefault();
            that.setValue();
        })
    }
    /**
     * 设置值
     */
    RadioClass.prototype.setValue = function(){
        var that = this,$form = $(that.form.dom)
        ,name = that.config.name.value
        ,value = that.original.value
        ,clickthis = that.original
        ,allradio = $form.find('[aiui-radio][name="'+name+'"]');
        allradio.prop('checked',false);
        allradio.next('.aiui-radio').removeClass('is-checked');
        clickthis.checked = true;
        that.$dom.addClass('is-checked');
        var callbackname = that.config.change.value;
        if(callbackname){
            var data = {
                value:that.original.value,
                name:name,
                original:that.original
            };
            if(window[callbackname] && typeof window[callbackname]==="function"){
                window[callbackname].call(that,data);
            }else if(form.event[callbackname] && typeof form.event[callbackname]==="function"){
                form.event[callbackname].call(that,data)
            }
        }
        if($(that.original)[0] && $(that.original).change){
            $(that.original).change();
        }
    }
    /**
     * checkbox表单渲染
     */
    CheckboxClass.prototype.render = function(){
        var that = this,$original = $(that.original),
        hasRender = $original.next('.aiui-checkbox'),
        $dom = $(aiui.render(that.template,that.config)),
        clickthis = that.original;
        that.$dom = $dom;
        //如果已经渲染了，就移除渲染的元素
        hasRender[0] && hasRender.remove();
        $original.after($dom);
        //绑定事件
        that.$dom.on('click',function(e){
            e.preventDefault();
            that.setValue();
        })
        //设置默认值
        if($(clickthis).attr('checked')!==undefined){//默认选中
            clickthis.checked = true;
            that.$dom.addClass('is-checked');
        }else{
            clickthis.checked = false;
            that.$dom.removeClass('is-checked');
        }
    }
    /**
     * checkbox设置值
     */
    CheckboxClass.prototype.setValue = function(){
        var that = this,$form = that.form.dom,
        name = that.config.name.value,
        value = that.original.value,
        clickthis = that.original;
        if(that.$dom.hasClass('is-disabled')){
            return false;
        }
        if($(clickthis).attr('checked')!==undefined){
            clickthis.checked = false;
            $(clickthis).removeAttr('checked');
            that.$dom.removeClass('is-checked');
        }else{
            clickthis.checked = true;
            $(clickthis).attr('checked','checked');
            that.$dom.addClass('is-checked');
        }
        var callbackname = that.config.change.value;
        if(callbackname){
            var data = {
                value:that.original.value,
                name:name,
                original:that.original
            };
            if(window[callbackname] && typeof window[callbackname]==="function"){
                window[callbackname].call(that,data);
            }else if(form.event[callbackname] && typeof form.event[callbackname]==="function"){
                form.event[callbackname].call(that,data)
            }
        }
        if($(that.original)[0] && $(that.original).change){
            $(that.original).change();
        }
    }
    /**
     * 开关表单渲染
     */
    SwitchClass.prototype.render = function(){
        var that = this,$original = $(that.original),
        hasRender = $original.next('.aiui-switch'),
        $dom = $(aiui.render(that.template,that.config));
        that.$dom = $dom;
        //如果已经渲染了，就移除渲染的元素
        hasRender[0] && hasRender.remove();
        $original.after($dom);
        //绑定事件
        that.$dom.on('click',function(e){
            e.preventDefault();
            that.setValue();
        })
        //默认必须是选中
        that.original.checked = true;
    }
    /**
     * 开关表单设置值
     */
    SwitchClass.prototype.setValue = function(){
        var that = this,name = that.config.name.value;
        that.original.checked = true;
        if(that.$dom.hasClass('is-checked')){
            that.original.value = that.config.falsevalue.value;
            that.$dom.removeClass('is-checked');
        }else{
            that.original.value = that.config.truevalue.value;
            that.$dom.addClass('is-checked');
        }
        var callbackname = that.config.change.value;
        if(callbackname){
            var data = {
                value:that.original.value,
                name:name,
                original:that.original
            };
            if(window[callbackname] && typeof window[callbackname]==="function"){
                window[callbackname].call(that,data);
            }else if(form.event[callbackname] && typeof form.event[callbackname]==="function"){
                form.event[callbackname].call(that,data)
            }
        }
        if($(that.original)[0] && $(that.original).change){
            $(that.original).change();
        }
    }
    /**
     * 渲染select
     */
    SelectClass.prototype.render = function(){
        var that = this,$dom = $(aiui.render(that.template,that.config))
        ,$original = $(that.original),hasRender = $original.next('.aiui-select');
        that.$dom = $dom;
        //如果已经渲染了，就移除渲染的元素
        hasRender[0] && hasRender.remove();
        $original.after($dom);
        var options = $original.find('*');
        that.$input = that.$dom.find('input');
        that.tags = {};
        that.optdata = [];
        $.each(options,function(index,option){
            var items = {};
            if(option.tagName.toLowerCase()==='optgroup'){ //分组
                items.value = '';
                items.label = $(option).attr('label');
                items.type = 'group';
            }else{
                items.value = $(option).val();
                items.label = $(option).text();
                items.disabled = typeof $(option).attr('disabled') !== "undefined" ? true : false;
                items.selected = typeof $(option).attr('selected') !=="undefined" ? true : false;
                that.tags[items.value] = $(aiui.render(['<span class="aiui-tag aiui-tag-small aiui-tag-info">',
                    '<span class="el-select-tag-text">{{label}}</span>',
                    '<i class="aiui-tag-close aiui-icon-close"></i>',
                '</span>'].join(''),items))[0];
            }
            that.optdata.push(items);
        })
        var popperhtml = ['<div class="aiui-popper aiui-select-dropdown" style="z-index:2001">',
            '<dl class="aiui-select-dropdown-list">',
            '{{each optdata opt i}}',
            '{{if opt.type=="group"}}',
            '<dt class="aiui-select-group-title">{{opt.label}}</dt>',
            '{{else}}',
            '<dd aiui-value="{{opt.value}}" class="aiui-select-dropdown-item" {{if opt.disabled}}disabled{{/if}} {{if opt.selected}}selected{{/if}}>{{opt.label}}</dd>',
            '{{/if}}',
            '{{/each}}',
            '</dl>',
            '<div class="aiui-popper-arrow" style="left:'+35+'px"></div>',
        '</div>'].join('');
        that.$optdom = $(aiui.render(popperhtml,that));
        that.$tagdom = that.$dom.find('.aiui-select-tags >span');
        that.initopt();
        //给dom绑定事件
        that.bindEvent();
        //设置初始值
        that.setValue(true);
    }
    /**
     * 初始化选项
     */
    SelectClass.prototype.initopt=function(){
        var that = this,$dom = that.$dom,$input = that.$input,
        $optdom=that.$optdom,$tagdom = that.$tagdom;
        $dom.append(that.$optdom);
        $optdom.css('min-width',$dom.outerWidth());
        $tagdom.parent().css('max-width',$input.width());
        that.$cleardom = $('<i class="aiui-select-caret aiui-icon-circle-close aiui-input-icon"></i>');
        that.transition = aiui.transition($optdom[0],{
            name:'aiui-zoom-in-top',
            duration:300,
            onenteractive:function(){
                that.popper.update();
            },
            onleaved:function(){
                $optdom.remove();
            }
        });
        that.srcollbar = new aiui.scroll($optdom.find('.aiui-select-dropdown-list')[0],{className:'aiui-select-dropdown-wrap'});
        that.popper = aiui.popper($dom[0], $optdom[0], {
            placement: 'bottom',
            arrowElement: 'aiui-popper-arrow',
            onUpdate:function(data){
                that.setting(data);
            },
            onCreate:function(data){
                $optdom.remove();
                that.setting(data);
            }
        });
    }
    /**
     * 动态改变弹出框的方向
     * @param {Object} data 
     */
    SelectClass.prototype.setting = function(data){
        var that = this;
        var x = {top:'bottom','bottom':'top'};
        that.transition.config.name = 'aiui-zoom-in-'+x[data.placement];
    }
    /**
     * 绑定事件
     */
    SelectClass.prototype.bindEvent = function(){
        var that = this,$dom = that.$dom,$optdom = that.$optdom;
        //点击其他地方关闭选项
        body.on('off',bodyclick).on('click',bodyclick);
        //文本框点击事件
        $dom.on('click',function(e){
            e.stopPropagation();
            document.onselectstart = function(){ return false};
            if(that.show){
                hide(e);
            }else{
                show(e);
            }
            document.onselectstart = null;
        })
        //多选点击事件
        $.each(that.tags,function(key,dom){
            aiui.event.bind(dom.children[1],'click',function(e){
                e.stopPropagation();
                $optdom.find('dd[aiui-value="'+key+'"]').removeAttr('selected');
                that.setValue();
            })
        })
        //下拉选项点击事件
        $optdom.find('dd').each(function(index,option){
            var $option = $(option);
            var value = $option.attr('aiui-value');
            aiui.event.bind(option,'click',function(e){
                e.preventDefault();
                //被禁用了
                if(typeof $option.attr('disabled')!=="undefined"){
                    return;
                }
                if(that.config.multiple.value){
                    if(typeof $option.attr('selected') !== "undefined"){
                        $option.removeAttr('selected');
                        that.setValue();
                    }else{
                        $option.attr('selected','selected');
                        that.setValue();
                    }
                }else{
                    $option.siblings().removeAttr('selected');
                    $option.attr('selected','');
                    that.setValue();
                    hide(1);
                }
            })
        })
        //清除选项按钮
        aiui.event.bind(that.$cleardom[0],'click',function(e){
            e.stopPropagation();
            $optdom.find('dd').removeAttr('selected');
            that.setValue();
        })
        //显示清除按钮
        var outTimer='';
        $dom.on('mouseover',function(e){
            clearTimeout(outTimer);
            clearshow();
        }).on('mouseout',function(e){
            if(that.data && that.config.clearable.value){
                outTimer = setTimeout(function(){
                    clearhide();
                },50)
            }
        })
        //清除按钮鼠标移入事件
        aiui.event.bind(that.$cleardom[0],'mouseover',function(e){
            clearTimeout(outTimer);
        })
        //清除按钮隐藏
        function clearhide(){
            that.$cleardom.remove();
            $dom.find('.aiui-input-suffix-inner').find('.aiui-icon-down').show();
        }
        //清除按钮显示
        function clearshow(){
            if(that.data && that.config.clearable.value){
                $dom.find('.aiui-input-suffix-inner').append(that.$cleardom);
                $dom.find('.aiui-input-suffix-inner').find('.aiui-icon-down').hide();
            }
        }
        /**
         * 下拉选项显示方法
         */
        function show(){
            var zindex=aiui.getMaxZIndex();
            $optdom.css('z-index',zindex+1);
            $optdom.css('display','none');
            body.append($optdom)
            that.transition.show();
            $dom.addClass('is-focus');
            that.show = true;
        }
        /**
         * 下拉选项隐藏方法
         */
        function hide(data){
            if(data==1){
                that.$optdom.remove();
                $dom.removeClass('is-focus');
                that.show = false;
            }else{
                that.transition.hide();
                $dom.removeClass('is-focus');
                that.show = false;
            }
        }
        /**
         * body点击事件
         */
        function bodyclick(e){
            e.preventDefault();
            if($dom.find(e.target)[0]){
                return;
            }
            if($dom.find(e.target)[0]){
                return;
            }
            if($optdom.find(e.target)[0] || $optdom[0]==e.target){
                return;
            }
            hide();
        }
    }
    /**
     * 设置值
     * @param {Boolean} init 是否是初始化
     */
    SelectClass.prototype.setValue = function(init=false){
        var that = this,selects=that.$optdom.find('dd[selected]'),
        $input = that.$input,$tagdom=that.$tagdom,$original = $(that.original);
        //如果是多选
        if(that.config.multiple.value){
            that.data = [];
            $tagdom.html('');
            $.each(selects,function(index,opt){
                var value = $(opt).attr('aiui-value');
                if(typeof value !== "undefined"){
                    $tagdom.append(that.tags[value]);
                    that.data.push(value);
                }
            })
            if(that.data.length>0){
                $input[0].placeholder = '';
            }else{
                $input[0].placeholder = that.config.placeholder.value;
            }
            var height = $tagdom.outerHeight() < 38 ? 38 : ($tagdom.outerHeight()+10)
            $input.css('height',height);
        }else{
            //单选
            var text = '';
            $.each(selects,function(index,opt){
                var value = $(opt).attr('aiui-value');
                text = $(opt).text();
                if(typeof value !== "undefined"){
                    that.data = value;
                }
            })
            if(text){
                $input[0].placeholder = '';
                $input[0].value = text;
            }else{
                $input[0].value = '';
                $input[0].placeholder = that.config.placeholder.value;
            }
        }
        $original.val(that.data);
        that.popper.update();
        if(!init){
            //不是初始化的时候调用回调函数
            if(that.config.selected.value){
                if(window[that.config.selected.value]){
                    window[that.config.selected.value].call(that,{
                        value:that.data,
                        original:that.original
                    })
                }else if(form.event[that.config.selected.value]){
                    form.event[that.config.selected.value].call(that,{
                        value:that.data,
                        original:that.original
                    })
                }
            }
            if($original[0] && $original.change){
                $original.change();
            };
        }
    }

    /**
     * 渲染表单元素
     * @param {string} type 渲染的类型
     * @param {string} filter 过滤器
     */
    FormClass.prototype.render = function(type,filter){
        var that = this,$dom = $(that.dom),
        Items={
            //单选
            radio:function(){
                var selector = 'input[type="radio"][aiui-radio]'+(filter? '[aiui-filter="'+filter+'"]' : '');
                var radios = $dom.find(selector);
                radios.each(function(index,radio){
                    radio.RadioClass = new RadioClass(that,radio);
                })
            },
            //多选
            checkbox:function(){
                var selector = 'input[type="checkbox"][aiui-checkbox]'+(filter? '[aiui-filter="'+filter+'"]' : '');
                var checkboxs = $dom.find(selector);
                $.each(checkboxs,function(index,checkbox){
                    checkbox.CheckboxClass = new CheckboxClass(that,checkbox);
                })
            },
            //开关
            switch:function(){
                var selector = 'input[type="checkbox"][aiui-switch]'+(filter? '[aiui-filter="'+filter+'"]' : '');
                var switchs = $dom.find(selector);
                $.each(switchs,function(index,checkbox){
                    checkbox.SwitchClass = new SwitchClass(that,checkbox);
                })
            },
            //下拉
            select:function(){
                var selector = 'select[aiui-select]'+(filter? '[aiui-filter="'+filter+'"]' : '');
                var selects = $dom.find(selector);
                $.each(selects,function(index,select){
                    select.SelectClass = new SelectClass(that,select);
                })
            }
        };
        if(type){
            Items[type] ? Items[type]() : aiui.error('不支持'+type+'表单渲染');
        }else{
            $.each(Items,function(index,item){
                item();
            })
        }
    }
    form.init();
    return form;
})